package com.team.mp.api.filter;

import com.alibaba.fastjson.JSON;
import com.team.mp.api.security.entity.LoginUser;
import com.team.mp.api.util.JwtUtil;
import com.team.mp.constants.RedisKey;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


/**
 * @projectName: springboot2
 * @package: com.feng.filter
 * @className: JwtAuthenticationTokenFilter
 * @author: Ladidol
 * @description:
 * @date: 2022/4/30 1:18
 * @version: 1.0
 */
@Component
@Slf4j
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
    @Resource
    StringRedisTemplate template;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        // 获取token
        String token = request.getHeader("mp-token");
        if(request.getRequestURI().contains("api/sysuser/login")){
            filterChain.doFilter(request, response);
            return;
        }
        // 为null 就放行
        if (token == null) {
            filterChain.doFilter(request, response);
            return;
        } else {
            // 解析token
            String id = JwtUtil.parseJwt(token);
            if (StringUtils.hasLength(id)) {
                if (template.hasKey(RedisKey.AUTH_TOKEN + id)) {
                    String json = template.opsForValue().get(RedisKey.AUTH_TOKEN + id);
                    // 从redis中读取信息
                    LoginUser loginUser = JSON.parseObject(json, LoginUser.class);
                    loginUser.setAuthorities();
                    log.info("认证拦截："+json);
                    // 获取权限信息封装到authentication中
                    UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken
                            = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
                    // 存入SecurityContextHolder, 其他filter会通过这个来获取当前用户信息
                    SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
                    // 放行
                    filterChain.doFilter(request, response);
                    return;
                } else {
                    throw new UsernameNotFoundException("令牌无效！");
                }
            } else {
                throw new UsernameNotFoundException("令牌是假的！");
            }
        }
    }
}
